#include "clientconnection.h"
#include <QDebug>
#include <QHostAddress>
#include <QHostAddress>

ClientConnection::ClientConnection(qintptr socketDescriptor, QObject *parent)
    : QObject(parent), m_descriptor(socketDescriptor), m_active(false) {
    m_socket = new QTcpSocket(this);
    m_connectionTime = QDateTime::currentDateTime();
}

ClientConnection::~ClientConnection() {
    stop();
}

void ClientConnection::start() {
    if (m_socket->setSocketDescriptor(m_descriptor)) {
        connect(m_socket, &QTcpSocket::readyRead, this, &ClientConnection::onReadyRead);
        connect(m_socket, &QTcpSocket::disconnected, this, &ClientConnection::onDisconnected);
        connect(m_socket, SIGNAL(error(QAbstractSocket::SocketError)),
                this, SLOT(onError(QAbstractSocket::SocketError)));

        m_active = true;
        QTextStream(stdout) << "Client connected:" << clientInfo()<<"\n";
    } else {
        emit errorOccurred(m_descriptor, "Failed to set socket descriptor");
    }
}

void ClientConnection::stop() {
    QMutexLocker locker(&m_mutex);
    if (m_socket && m_socket->state() != QAbstractSocket::UnconnectedState) {
        m_socket->disconnectFromHost();
        if (m_socket->state() != QAbstractSocket::UnconnectedState) {
            m_socket->waitForDisconnected(5000);
        }
    }
    m_active = false;
}

void ClientConnection::sendMessage(const QString &message) {
    QMutexLocker locker(&m_mutex);
    if (m_socket && m_socket->state() == QAbstractSocket::ConnectedState) {
        m_socket->write(message.toUtf8());
        m_socket->flush();
    }
}

QString ClientConnection::clientInfo() const {
    QMutexLocker locker(&m_mutex);
    if (m_socket) {
        return QString("%1:%2").arg(m_socket->peerAddress().toString())
                .arg(m_socket->peerPort());
    }
    return QString("Unknown:%1").arg(m_descriptor);
}

QDateTime ClientConnection::connectionTime() const {
    QMutexLocker locker(&m_mutex);
    return m_connectionTime;
}

bool ClientConnection::isActive() const {
    QMutexLocker locker(&m_mutex);
    return m_active;
}

void ClientConnection::onReadyRead() {
    QString message = QString::fromUtf8(m_socket->readAll()).trimmed();
    emit messageReceived(m_descriptor, message);
}

void ClientConnection::onDisconnected() {
    QTextStream(stdout) << "Client disconnected:" << clientInfo()<<"\n";
    m_active = false;
    emit clientDisconnected(m_descriptor);
}

void ClientConnection::onError(QAbstractSocket::SocketError error) {
    Q_UNUSED(error);
    emit errorOccurred(m_descriptor, m_socket->errorString());
}
